package com.jack.lib.ui.widget

import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.app.AppCompatActivity
import android.view.MotionEvent
import com.jack.lib.core.utils.DeviceInfo
import java.util.ArrayList

/**
 * Created by chong on 2017/7/28.
 */
class MainEventLayout : JFrameLayout {


    private val mOnDispatchTouchEventListeners: MutableList<OnDispatchTouchEventListener> = ArrayList()

    private var mOnTouchListener: OnTouchListener? = null
    private var mOnDownListener: OnDownListener? = null
    private var mOnActivityFinish: OnActivityFinish? = null
    private var mSlideCloseEnable = true
    private var mOldMoveX = 0f
    private var mOldMoveY = 0f
    private var mTotalMove = 0f
    private var mLastTime: Long = 0
    private var mActivity: AppCompatActivity? = null
    private var isClose = false
    private var mScreenWide: Int

    constructor(context: Context?) : super(context!!) {
        mScreenWide = DeviceInfo.sScreenRect.width()
    }

    constructor(context: Context?, attrs: AttributeSet?) : super(
        context!!, attrs
    ) {
        mScreenWide = DeviceInfo.sScreenRect.width()
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> return down(ev)
            MotionEvent.ACTION_MOVE -> move(ev)
            MotionEvent.ACTION_UP -> return up(ev)
            MotionEvent.ACTION_CANCEL -> cancel(ev)
        }
        return super.dispatchTouchEvent(ev)
    }

    private fun down(ev: MotionEvent): Boolean {
        mTotalMove = 0f
        mOldMoveX = ev.x
        mOldMoveY = ev.y
        if (mOnDownListener != null) mOnDownListener!!.onDown(ev)
        for (onDispatchTouchEventListener in mOnDispatchTouchEventListeners) {
            if (onDispatchTouchEventListener.onDown(ev)) {
                return true
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    private fun move(ev: MotionEvent) {
        for (onDispatchTouchEventListener in mOnDispatchTouchEventListeners) {
            onDispatchTouchEventListener.onMove(ev)
        }
        if (mSlideCloseEnable) {
            if (mOldMoveX == 0f) mOldMoveX = ev.x
            if (mOldMoveY == 0f) mOldMoveY = ev.y
            if (mLastTime == 0L) mLastTime = System.currentTimeMillis()
            if (ev.x - mOldMoveX < 0) mTotalMove += Math.abs(ev.x - mOldMoveX)
            if (ev.x - mOldMoveX > 14 * mScreenWide / 1080 && ev.x - mOldMoveX >
                Math.abs(ev.y - mOldMoveY) * 2f && mTotalMove < 40 * mScreenWide / 1080
            ) {
                isClose = true
                mLastTime = System.currentTimeMillis()
            } else {
                isClose = false
            }
            mOldMoveX = ev.x
            mOldMoveY = ev.y
        }
    }

    private fun up(ev: MotionEvent): Boolean {
        if (mSlideCloseEnable) {
            if (isClose && System.currentTimeMillis() - mLastTime < 200 && mActivity != null) {
                if (mOnActivityFinish == null || mOnActivityFinish!!.onFinish()) {
                    mActivity!!.finish()
                    return true
                }
            }
        }
        for (onDispatchTouchEventListener in mOnDispatchTouchEventListeners) {
            onDispatchTouchEventListener.onUp(ev)
        }
        return super.dispatchTouchEvent(ev)
    }

    private fun cancel(ev: MotionEvent) {
        for (onDispatchTouchEventListener in mOnDispatchTouchEventListeners) {
            onDispatchTouchEventListener.onCancel(ev)
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (mOnTouchListener != null) mOnTouchListener!!.onTouch(event)
        return true
    }

    fun setSlideCloseEnable(slideCloseEnable: Boolean, activity: AppCompatActivity?) {
        mSlideCloseEnable = slideCloseEnable
        mActivity = activity
    }

    fun setSlideCloseEnable(slideCloseEnable: Boolean) {
        mSlideCloseEnable = slideCloseEnable
    }

    abstract class OnDispatchTouchEventListener {
        fun onDown(event: MotionEvent?): Boolean {
            return false
        }

        fun onMove(event: MotionEvent?) {}
        fun onUp(event: MotionEvent?) {}
        fun onCancel(event: MotionEvent?) {}
    }

    /**
     * 左滑关闭Activity的监听
     */
    interface OnActivityFinish {
        /**
         * 在左滑手势满足条件时回调,如果不设置改监听,会默认关闭Activity
         * @return true则会关闭Activity,false 则不会
         */
        fun onFinish(): Boolean
    }

    interface OnDownListener {
        fun onDown(event: MotionEvent?)
    }

    interface OnTouchListener {
        fun onTouch(event: MotionEvent?)
    }

    fun addOnDispatchTouchEventListener(onDispatchTouchEventListener: OnDispatchTouchEventListener) {
        mOnDispatchTouchEventListeners.add(onDispatchTouchEventListener)
    }

    fun setOnActivityFinish(onActivityFinish: OnActivityFinish?) {
        mOnActivityFinish = onActivityFinish
    }

    fun setOnDownListener(onDownListener: OnDownListener?) {
        mOnDownListener = onDownListener
    }

    fun setOnTouchEvent(onTouchEvent: OnTouchListener?) {
        mOnTouchListener = onTouchEvent
    }
}